package com.syt.faceservice2.face;

import com.alibaba.fastjson.JSONObject;
import com.arcsoft.face.*;
import com.arcsoft.face.enums.ImageFormat;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.DataBufferByte;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.List;

@Controller
public class FaceEngineControllerTwo {

    private static List<StudentBean> studentBeanList = new ArrayList<>();
    private static int stuNum = 4;

    @Value("${syt.upload}")
    String path;

    @Value("${appId}")
    private String appId;

    @Value("${sdkKey}")
    private String sdkKey;

    @Value("${img}")
    private String img;

    @Value("${ip}")
    private String ip;

    private FaceEngine faceEngine;
    JSONObject jsonObject = new JSONObject();

    /**
     * 实现传入人脸检测生成 人脸数据
     */
    @PostMapping("api/createFace2")
    @ResponseBody
    public Object createFace(MultipartFile file) {

        jsonObject.clear();

        String filePath = path + "/" + file.getOriginalFilename();

        try {
            jsonObject.put("filepath", filePath);
            File destFile = new File(filePath);
            if(!destFile.getParentFile().exists()){
                destFile.mkdirs();
            }
            file.transferTo(destFile);
            jsonObject.put("src", "http://" + ip + ":8001/" + file.getOriginalFilename());

            file.getOriginalFilename();

            createFace(destFile);

        } catch (Exception e) {
            e.printStackTrace();
            jsonObject.put("msg", "上传失败," + e.getMessage());
        }
        return jsonObject;
    }

    @PostMapping("weixt/api/base_stu_listByMacid")
    @ResponseBody
    public Object testStudentList() {

        jsonObject.clear();

        Map<String, String> ret = new HashMap<>();
        ret.put("msg", "");
        ret.put("code", "200");

        jsonObject.put("ret", ret);

        List<StudentBean> studentList = new ArrayList<>();
        /**
         * action : INSERT
         * campusid : 196
         * className : 三年（1）班
         * classid : 401427117
         * committeeNames :
         * createTime : 2019-seven-twentyfour seventeen:55:51
         * datapath :
         * name : 分为非
         * picpath : http://qiniu.weixiaotong.com/boyteacher.jpg
         * sex : 1 性别1男：2女
         * stuNumber :
         * stuid : 1561257844
         * (Long studentID, String action, int campusid,
         *                        String className, Long classid, String committeeNames,
         *                        String createTime, String datapath, String facedataPath, String name,
         *                        String picpath, String sex, String stuNumber, int stuid)
         */
        StudentBean studentBean = new StudentBean
                (5001607L, "INSERT", 1615, "初一(1)班", 27960L,
                        "2020-03-10 11:44:39", null, null,
                        "http://47.115.43.73:8001/b045abc5baa1cc3ca70c6cc19abc12cb2181bb51.data", "陈佳康",
                        "http://static.weixiaotong.com.cn/b045abc5baa1cc3ca70c6cc19abc12cb2181bb51.jpg", "1", null, 5001607);
        StudentBean studentBean2 = new StudentBean
                (5015745L, "INSERT", 1615, "初一(1)班", 27960L,
                        "2020-03-10 11:44:39", null, null,
                        "http://47.115.43.73:8001/a897341b4309cf614f87521382631d03.png.data", "tom",
                        "http://static.weixiaotong.com.cn//a897341b4309cf614f87521382631d03.png", "1", null, 5015745);

        StudentBean studentBean3 = new StudentBean
                (5014600L, "INSERT", 1615, "初一(1)班", 27960L,
                        "2020-03-10 11:44:39", null, null,
                        "http://47.115.43.73:8001/cw.png.data", "sam",
                        "http://47.115.43.73:8001/cw.png", "1", null, 5014600);
        StudentBean studentBean4 = new StudentBean
                (5014661L, "INSERT", 1615, "初一(1)班", 27960L,
                        "2020-03-10 11:44:39", null, null,
                        "http://47.115.43.73:8001/69979E090FECCD5286A7DF8360FC06B3.data", "zpp",
                        "http://47.115.43.73:8001/69979E090FECCD5286A7DF8360FC06B3.jpg", "1", null, 5014661);


        studentList.add(studentBean);
        studentList.add(studentBean2);
        studentList.add(studentBean3);
        studentList.add(studentBean4);
        studentList.addAll(studentBeanList);

        jsonObject.put("data", studentList);

        jsonObject.put("v", "");
        jsonObject.put("api", "stu_listByMacid");

        return jsonObject;
    }

    /**
     * 创建人脸特征值
     * @param faceFile
     */
    public void createFace(File faceFile) {

        //获取最后一个.的位置
        int lastIndexOf = faceFile.getName().lastIndexOf(".");
        //获取文件的后缀名 .jpg
        String suffix = faceFile.getName().substring(lastIndexOf);
        if (suffix.equals(".png")) {
            pngPackinJpg(faceFile);
            faceFile = new File(faceFile.getAbsolutePath() + ".jpg");
        }

        if (faceEngine == null) {
            initFaceEngine();
        }
        //人脸检测
        ImageInfo imageInfo = getRGBData(faceFile);

        List<FaceInfo> faceInfoList = new ArrayList<FaceInfo>();
        int errorCode = faceEngine.detectFaces(imageInfo.getRgbData(), imageInfo.getWidth(), imageInfo.getHeight(), ImageFormat.CP_PAF_BGR24, faceInfoList);
        System.out.println(faceInfoList);
        jsonObject.put("人脸检测结果", errorCode);
        jsonObject.put("faceInfoList", faceInfoList);

        //特征提取
        FaceFeature faceFeature = new FaceFeature();
        errorCode = faceEngine.extractFaceFeature(imageInfo.getRgbData(), imageInfo.getWidth(), imageInfo.getHeight(), ImageFormat.CP_PAF_BGR24, faceInfoList.get(0), faceFeature);
        System.out.println("特征值大小：" + faceFeature.getFeatureData().length);
        jsonObject.put("特征提取结果", errorCode);
        jsonObject.put("特征值大小", faceFeature.getFeatureData().length);
        jsonObject.put("faceData", Arrays.toString(faceFeature.getFeatureData()));

        // 保存特征文件
        String dataName = faceFile.getName().substring(0, faceFile.getName().lastIndexOf("."));
        String fileDataPath = path + "/" + dataName + ".data";
        File faceData = new File(fileDataPath);
        if (faceData.exists()) {
            // 创建不存在的文件
//            faceData.delete();
            faceData.mkdirs();
        }

        FileOutputStream fileOutputStream = null;

        try {
            fileOutputStream = new FileOutputStream(faceData);
            fileOutputStream.write(faceFeature.getFeatureData(), 0, faceFeature.getFeatureData().length);

            jsonObject.put("dataPath", "http://" + ip + ":8001/" + dataName + ".data");

            StudentBean studentBean = new StudentBean
                    (5014671L + stuNum, "INSERT", 1615, "初一(1)班", 27960L,
                            "2020-03-10 11:44:39", null, null,
                            jsonObject.getString("dataPath"), "test",
                            jsonObject.getString("filepath"), "1", null, 5014671 + stuNum);

            studentBeanList.add(studentBean);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            System.out.println("文件流异常");
            jsonObject.put("errorFile", "文件流异常");
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("数据写入异常");
            jsonObject.put("errorFile", "数据写入异常");
        } finally {
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
    }

    /**
     * 初始化人脸引擎
     */
    private void initFaceEngine() {
        faceEngine = new FaceEngine();
        //激活引擎
        faceEngine.active(appId, sdkKey);

        //引擎配置
        EngineConfiguration engineConfiguration = EngineConfiguration.builder().functionConfiguration(
                FunctionConfiguration.builder()
                        .supportAge(true)
                        .supportFace3dAngle(true)
                        .supportFaceDetect(true)
                        .supportFaceRecognition(true)
                        .supportGender(true)
                        .build()).build();

        //初始化引擎
        faceEngine.init(engineConfiguration);
    }

    public ImageInfo getRGBData(File file) {
        if (file == null) {
            return null;
        }
        ImageInfo imageInfo;
        try {
            //将图片文件加载到内存缓冲区
            BufferedImage image = ImageIO.read(file);
            imageInfo = bufferedImage2ImageInfo(image);
        } catch (IOException e) {
            jsonObject.put("errRGBData", e.getMessage());
            e.printStackTrace();
            return null;
        }
        return imageInfo;
    }

    private ImageInfo bufferedImage2ImageInfo(BufferedImage image) {
        ImageInfo imageInfo = new ImageInfo();
        int width = image.getWidth();
        int height = image.getHeight();
        // 使图片居中
        width = width & (~3);
        height = height & (~3);
        imageInfo.width = width;
        imageInfo.height = height;
        //根据原图片信息新建一个图片缓冲区
        BufferedImage resultImage = new BufferedImage(width, height, image.getType());
        //得到原图的rgb像素矩阵
        int[] rgb = image.getRGB(0, 0, width, height, null, 0, width);
        //将像素矩阵 绘制到新的图片缓冲区中
        resultImage.setRGB(0, 0, width, height, rgb, 0, width);
        //进行数据格式化为可用数据
        BufferedImage dstImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
        if (resultImage.getType() != BufferedImage.TYPE_3BYTE_BGR) {
            ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB);
            ColorConvertOp colorConvertOp = new ColorConvertOp(cs, dstImage.createGraphics().getRenderingHints());
            colorConvertOp.filter(resultImage, dstImage);
        } else {
            dstImage = resultImage;
        }

        //获取rgb数据
        imageInfo.rgbData = ((DataBufferByte) (dstImage.getRaster().getDataBuffer())).getData();
        return imageInfo;
    }

    /**
     * png -> jpg
     */
    public static void pngPackinJpg(File file) {
        BufferedImage bufferedImage;
        try {
            bufferedImage= ImageIO.read(file);
            BufferedImage newBufferedImage = new BufferedImage(
                    bufferedImage.getWidth(), bufferedImage.getHeight(),
                    BufferedImage.TYPE_INT_RGB);
            // TYPE_INT_RGB:创建一个RBG图像，24位深度，成功将32位图转化成24位
            newBufferedImage.createGraphics().drawImage(bufferedImage, 0, 0,
                    Color.WHITE, null);
            // write to jpeg file
            file = new File(file.getAbsolutePath() + ".jpg");
            ImageIO.write(newBufferedImage, "jpg", file);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        File file = new File("/Users/space/Desktop/cw.png");
        //获取最后一个.的位置
        int lastIndexOf = file.getName().lastIndexOf(".");
        //获取文件的后缀名 .jpg
        String suffix = file.getName().substring(lastIndexOf);
        if (suffix.equals(".png")) {
            pngPackinJpg(file);
        }
        System.out.println(file.getName());
    }
}


